<template>
    <div class="cp-full-page" id="page-scroll">
        <div ref="element" :class="{ activeTranstion: isCloseTranstion }" class="inner-box" @mousewheel="mousewheel"
            @touchstart="handleTouchStart" @touchend="handleTouchEnd" @touchmove="handleTouchMove">
            <slot></slot>
        </div>
        <div :class="['cp-full-dot', props.position]">
            <div v-for="item, index in props.items" @click="changeBac(index)" class="cp-full-dot-item">
                <div class="cp-full-dot-item-bg" :class="{ active: index === $index }"></div>
                <div v-if="props.showTitle" v-show="index === $index" class="show-dec">{{ item.title }}</div>
            </div>
        </div>
    </div>
</template>

<script setup lang="ts">
import { computed, ref, watchEffect } from 'vue';
defineOptions({
    name: 'CyberFullPage',
})
type Item = {
    title: string;
    content?: string;
}
const props = defineProps({
    items: {
        type: Array as () => Array<Item>,
        default: [{ title: '标题1' }]
    },
    position: {
        type: String,
        default: 'right'
    },
    showTitle: {
        type: Boolean,
        default: true
    }
})
const emits = defineEmits(['toNext', 'toLast', 'change'])
// ELEMENT
const element = ref()
watchEffect(() => {
    if (element.value?.style) {
        element.value.style.transform = transformScroll.value
        // element.value.style.top = transformScroll.value
    }
})

//HEIGHT
const windowHeight = computed(() => {
    // 高度变化时需要关闭动画
    isCloseTranstion.value = true

    let sheight = 0
    if (document.getElementById('page-scroll')?.clientHeight) {
        sheight = document.getElementById('page-scroll')?.clientHeight ?? 0
    } else {
        sheight = window.innerHeight
    }
    return sheight
})
const transformScroll = computed(() => {
    return `translateY(-${$index.value * windowHeight.value}px)`
    // return `-${$index.value * windowHeight.value}px`
})

const isCloseTranstion = ref(false) //控制是否显示动画效果
const canRun = ref(true) //节流控制器

function mousewheel(e) {
    isCloseTranstion.value = false
    if (canRun.value) {
        canRun.value = false
        goScroll(e)
        setTimeout(() => {
            canRun.value = true
        }, 500)
    }
}

//#region 移动端
const startY = ref(0) //记录开始位置
const endY = ref(0) //记录结束位置
const moveDistance = ref(0) //滑动距离

// 触摸开始
function handleTouchStart(e) {
    startY.value = e.touches[0].pageY || e.changedTouches[0].pageY
}

// 触摸抬起
function handleTouchEnd(e) {
    e.preventDefault()
    // 抬起时开启动画
    isCloseTranstion.value = false
    // 计算结束距离
    endY.value = e.changedTouches[0].pageY || e.touches[0].pageY
    // 计算移动距离，判断应该上一页还是下一页，直接更改index即可在原先基础上整页移动
    moveDistance.value = endY.value - startY.value
    // 这里我做了一个最小值 大于50才翻页
    if (Math.abs(moveDistance.value) >= 60) {
        if ($index.value < props.items.length - 1 && moveDistance.value < 0) {
            $index.value++
        }
        if ($index.value > 0 && moveDistance.value > 0) {
            $index.value--
        }
    } else {
        // 当临界值小于60意味着不需要翻页 就恢复原来的位置即可
        console.log("else", -$index.value * windowHeight.value)
        element.value.style.transform = `translateY(-${$index.value * windowHeight.value}px)`
        // element.value.style.top = `-${$index.value * windowHeight.value}px`
    }
}

// 触摸移动
function handleTouchMove(e) {
    isCloseTranstion.value = true // 开始移动 关闭动画
    // e.stopPropagation()
    e.preventDefault()
    // if (isIOS()) {
    //   return
    // }
    moveDistance.value = (e.changedTouches[0].pageY || e.touches[0].pageY) - startY.value // 计算移动距离\
    //判断临界点
    const isCriticalPoint =
        ($index.value === props.items.length - 1 && moveDistance.value < 0) ||
        ($index.value === 0 && moveDistance.value > 0)
    // 如果是临界点就直接返回
    if (isCriticalPoint) {
        return
    }
    // 否则直接对内层容器应用 随之移动
    console.log("else", -$index.value * windowHeight.value + moveDistance.value * -1)

    element.value.style.transform = `translateY(-${$index.value * windowHeight.value + moveDistance.value * -1}px)`
    // element.value.style.top = `-${$index.value * windowHeight.value + moveDistance.value * -1}px`
}
//#endregion

//ANOTHER writting about full-page
// const { y } = useScroll(document)
// watchThrottled(
//   y,
//   (newValue, oldValue) => {
//     if (newValue > oldValue && newValue > 120) {
//       next()
//     } else {
//       last()
//     }
//   },
//   { throttle: 300 },
// )

function goScroll(e) {
    //e.wheelDelta 用来判断上一个下一个 <0 下一个 >0上一个
    if (e.wheelDelta < 0) {
        next()
        emits('change', { from: props.items[$index.value - 1], to: props.items[$index.value], type: 'next' })
    } else {
        last()
        emits('change', { from: props.items[$index.value + 1], to: props.items[$index.value], type: 'last' })
    }
}

//$INDEX
const $index = ref(0) //索引控制第几个显示
// 下一个
function next() {
    if ($index.value < props.items.length - 1) {
        $index.value++
        emits('toNext', $index.value)
    }
}
// 上一个
function last() {
    if ($index.value > 1 || $index.value === 1) {
        $index.value--
        emits('toLast', $index.value)

    }
}

// 点击切换
function changeBac(index) {
    isCloseTranstion.value = false
    $index.value = index
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style lang="scss" scoped>
.activeTranstion {
    transition: all 0ms ease 0s !important;
}

.active {
    display: inline-block;
    width: 12px !important;
    height: 12px !important;
    transition: all .2s;
}

.cp-full-page {
    width: 100%;
    height: 100%;
    overflow: hidden;
    position: relative;

    .inner-box {
        position: relative;
        width: 100%;
        transition: all ease-in-out 0.3s;
    }

    .cp-full-dot {
        list-style: none;
        position: absolute;
        right: 0px;
        top: 50%;
        transform: translateY(-50%);
        transition: all ease-in-out .2s;

        &.left {
            left: 0px;
            top: 50%;
            transform: translateY(-50%);
            width: 28px;

            .cp-full-dot-item {
                .show-dec {
                    text-align: left;
                    left: 20px;
                    flex-direction: row;

                    &::before {
                        width: 40px;
                        height: 1px;
                    }
                }
            }
        }

        &.top {
            left: 50%;
            top: 0px;
            transform: translateX(-50%);
            display: flex;
            justify-content: center;
            height: 28px;

            .cp-full-dot-item {
                .show-dec {
                    text-align: center;
                    top: 20px;
                    flex-direction: column;
                    align-items: center;
                    transform: translateX(60px);

                    &::before {
                        width: 1px;
                        height: 40px;
                    }
                }
            }
        }

        &.bottom {
            left: 50%;
            bottom: 0px;
            top: auto;
            transform: translateX(-50%);
            display: flex;
            justify-content: center;
            height: 28px;

            .cp-full-dot-item {
                .show-dec {
                    text-align: center;
                    bottom: 20px;
                    flex-direction: column-reverse;
                    align-items: center;
                    transform: translateX(60px);

                    &::before {
                        width: 1px;
                        height: 40px;
                    }
                }
            }
        }

        .cp-full-dot-item {
            height: 14px;
            width: 14px;
            margin: 7px;
            display: flex;
            align-items: center;
            justify-content: center;
            position: relative;
            transition: all ease-in-out .2s;

            .cp-full-dot-item-bg {
                border-radius: 100%;
                border: #fff solid 1px;
                width: 4px;
                height: 4px;
                display: inline-block;
                // background-color: #fff;
                box-shadow: 0 0 5px 1px #666;
                transition: all ease-in-out 0.2s;
            }

            &:hover .cp-full-dot-item-bg {
                width: 10px;
                height: 10px;
                // background-color: #fff;
                box-shadow: 0 0 5px 1px #666;
                cursor: pointer;
                transition: all ease-in-out .2s;
            }

            .show-dec {
                text-align: right;
                position: absolute;
                width: 100px;
                right: 20px;
                padding: 1px;
                display: flex;
                flex-direction: row-reverse;
                // color: #fff;
                transition: all linear 0.1s;
                font-size: 12px;

                &::before {
                    display: inline-block;
                    content: "";
                    width: 40px;
                    height: 1px;
                    background-color: #666;
                    margin-top: 9px;
                    margin-left: 4px;
                    transition: all ease-in-out .2s;
                }
            }
        }
    }
}
</style>